W raporcie wykorzystano następujące biblioteki:
library(knitr)
library(dplyr)
library(tidyr)
library(ggplot2)
library(plotly)
library(ggcorrplot)
library(caret)
Materials Project to inicjatywa naukowa Departamentu Energii USA, której celem jest dostarczanie otwartych danych i narzędzi do analizy materiałów. Jednym z kluczowych zbiorów danych dostępnych w ramach Materials Project jest baza danych dotycząca materiałów używanych w bateriach, która zawiera informacje o ich składzie chemicznym i parametrach wydajnościowych.
df <- read.csv("./data/mp_batteries.csv", na.strings="?")
df <- tbl_df(df)
| Nazwa atrybutu | Opis |
|---|---|
| Battery ID | Identyfikator baterii. |
| Battery Formula | Wzór chemiczny materiału baterii. |
| Working Ion | Główny jon, który odpowiada za transport ładunku w baterii. |
| Formula Charge | Wzór chemiczny materiału baterii w stanie naładowanym. |
| Formula Discharge | Wzór chemiczny materiału baterii w stanie rozładowanym. |
| Max Delta Volume | Zmiana objętości w % dla danego kroku napięcia za pomocą wzoru : max(charge, discharge)/min(charge, discharge) -1. |
| Average Voltage | Średnie napięcie dla poszczególnego kroku napięcia. |
| Gravimetric Capacity | Pojemność grawimetryczna, czyli ilość energii na jednostkę masy (mAh/g). |
| Volumetric Capacity | Pojemność wolumetryczna, czyli ilość energii na jednostkę objętości (mAh/cm³). |
| Gravimetric Energy | Gęstość energii w odniesieniu do masy baterii (Wh/kg). |
| Volumetric Energy | Gęstość energii w odniesieniu do objętości baterii (Wh/L). |
| Atomic Fraction Charge | Udział atomowy składników w stanie naładowanym. |
| Atomic Fraction Discharge | Udział atomowy składników w stanie rozładowanym. |
| Stability Charge | Wskaźnik stabilności materiału w stanie naładowanym. |
| Stability Discharge | Wskaźnik stabilności materiału w stanie rozładowanym. |
| Steps | Liczba odrębnych kroków napięcia od pełnego naładowania do rozładowana, oparta na stabilnych stanach pośrednich. |
| Max Voltage Step | Maksymalna bezwzględna różnica między sąsiednimi krokami napięcia. |
Poniżej znajduje się lista kroków wykonanych na zbiorze danych w celu przygotowania go do anaizy.
## tibble [4,351 × 17] (S3: tbl_df/tbl/data.frame)
## $ Battery.ID : chr [1:4351] "mp-30_Al" "mp-1022721_Al" "mp-8637_Al" "mp-129_Al" ...
## $ Battery.Formula : chr [1:4351] "Al0-2Cu" "Al1-3Cu" "Al0-5Mo" "Al0-12Mo" ...
## $ Working.Ion : chr [1:4351] "Al" "Al" "Al" "Al" ...
## $ Formula.Charge : chr [1:4351] "Cu" "AlCu" "Mo" "Mo" ...
## $ Formula.Discharge : chr [1:4351] "Al2Cu" "Al3Cu" "Al5Mo" "Al12Mo" ...
## $ Max.Delta.Volume : num [1:4351] 3.04 1.24 4.76 12.72 12.49 ...
## $ Average.Voltage : num [1:4351] 0.089 -0.0216 0.1228 0.0431 0.0292 ...
## $ Gravimetric.Capacity : num [1:4351] 1368 1113 1742 2299 1901 ...
## $ Volumetric.Capacity : num [1:4351] 5563 4419 7176 7346 7333 ...
## $ Gravimetric.Energy : num [1:4351] 121.8 -24 213.8 99.1 55.6 ...
## $ Volumetric.Energy : num [1:4351] 495.3 -95.4 880.9 316.8 214.4 ...
## $ Atomic.Fraction.Charge : num [1:4351] 0 0.5 0 0 0 ...
## $ Atomic.Fraction.Discharge: num [1:4351] 0.667 0.75 0.833 0.923 0.923 ...
## $ Stability.Charge : num [1:4351] 0 0.0741 0.4115 0 0 ...
## $ Stability.Discharge : num [1:4351] 0 0.0962 0.0452 0.0114 0 ...
## $ Steps : int [1:4351] 1 1 1 1 1 1 1 1 1 1 ...
## $ Max.Voltage.Step : num [1:4351] 0 0 0 0 0 0 0 0 0 0 ...
## # A tibble: 6 × 17
## Battery.ID Battery.Formula Working.Ion Formula.Charge Formula.Discharge
## <chr> <chr> <chr> <chr> <chr>
## 1 mp-30_Al Al0-2Cu Al Cu Al2Cu
## 2 mp-1022721_Al Al1-3Cu Al AlCu Al3Cu
## 3 mp-8637_Al Al0-5Mo Al Mo Al5Mo
## 4 mp-129_Al Al0-12Mo Al Mo Al12Mo
## 5 mp-91_Al Al0-12W Al W Al12W
## 6 mp-1055908_Al Al0-12Mn Al Mn MnAl12
## # ℹ 12 more variables: Max.Delta.Volume <dbl>, Average.Voltage <dbl>,
## # Gravimetric.Capacity <dbl>, Volumetric.Capacity <dbl>,
## # Gravimetric.Energy <dbl>, Volumetric.Energy <dbl>,
## # Atomic.Fraction.Charge <dbl>, Atomic.Fraction.Discharge <dbl>,
## # Stability.Charge <dbl>, Stability.Discharge <dbl>, Steps <int>,
## # Max.Voltage.Step <dbl>
Sprawdzenie ile jest pustych wartościami w poszczególnych kolumnach oraz ile w zbiorze jest zduplikowanych wierszy.
colSums(is.na(df))
## Battery.ID Battery.Formula Working.Ion
## 0 0 0
## Formula.Charge Formula.Discharge Max.Delta.Volume
## 0 0 0
## Average.Voltage Gravimetric.Capacity Volumetric.Capacity
## 0 0 0
## Gravimetric.Energy Volumetric.Energy Atomic.Fraction.Charge
## 0 0 0
## Atomic.Fraction.Discharge Stability.Charge Stability.Discharge
## 0 0 0
## Steps Max.Voltage.Step
## 0 0
duplicates_count <- sum(duplicated(df))
print(paste("Liczba zduplikowanych wierszy:", duplicates_count))
## [1] "Liczba zduplikowanych wierszy: 0"
Z powodu braku zduplikowanych danych oraz braku wartości pustych w zbiorze - dane nie wymagają czyszczenia.
Zbiór danych składa się z 4351 wierszy (obserwacji) i 17 kolumn (atrybutów).
kable(summary(df %>% select(Max.Delta.Volume:Volumetric.Energy)))
| Max.Delta.Volume | Average.Voltage | Gravimetric.Capacity | Volumetric.Capacity | Gravimetric.Energy | Volumetric.Energy | |
|---|---|---|---|---|---|---|
| Min. : 0.00002 | Min. :-7.755 | Min. : 5.176 | Min. : 24.08 | Min. :-583.5 | Min. :-2208.1 | |
| 1st Qu.: 0.01747 | 1st Qu.: 2.226 | 1st Qu.: 88.108 | 1st Qu.: 311.62 | 1st Qu.: 211.7 | 1st Qu.: 821.6 | |
| Median : 0.04203 | Median : 3.301 | Median : 130.691 | Median : 507.03 | Median : 401.8 | Median : 1463.8 | |
| Mean : 0.37531 | Mean : 3.083 | Mean : 158.291 | Mean : 610.62 | Mean : 444.1 | Mean : 1664.0 | |
| 3rd Qu.: 0.08595 | 3rd Qu.: 4.019 | 3rd Qu.: 187.600 | 3rd Qu.: 722.75 | 3rd Qu.: 614.4 | 3rd Qu.: 2252.3 | |
| Max. :293.19322 | Max. :54.569 | Max. :2557.627 | Max. :7619.19 | Max. :5926.9 | Max. :18305.9 |
kable(summary(df %>% select(Atomic.Fraction.Charge:Max.Voltage.Step)))
| Atomic.Fraction.Charge | Atomic.Fraction.Discharge | Stability.Charge | Stability.Discharge | Steps | Max.Voltage.Step | |
|---|---|---|---|---|---|---|
| Min. :0.00000 | Min. :0.007407 | Min. :0.00000 | Min. :0.00000 | Min. :1.000 | Min. : 0.0000 | |
| 1st Qu.:0.00000 | 1st Qu.:0.086957 | 1st Qu.:0.03301 | 1st Qu.:0.01952 | 1st Qu.:1.000 | 1st Qu.: 0.0000 | |
| Median :0.00000 | Median :0.142857 | Median :0.07319 | Median :0.04878 | Median :1.000 | Median : 0.0000 | |
| Mean :0.03986 | Mean :0.159077 | Mean :0.14257 | Mean :0.12207 | Mean :1.167 | Mean : 0.1503 | |
| 3rd Qu.:0.04762 | 3rd Qu.:0.200000 | 3rd Qu.:0.13160 | 3rd Qu.:0.09299 | 3rd Qu.:1.000 | 3rd Qu.: 0.0000 | |
| Max. :0.90909 | Max. :0.993333 | Max. :6.48710 | Max. :6.27781 | Max. :6.000 | Max. :26.9607 |
W tym zbiorze można odczytać następujące cechy statystyczne:
Poniżej znajduje się analiza zbioru danych w celu zbadania rozkładów wartości poszczególnych atrybutów oraz sprawdzenia występujących między nimi korelacji.
p <- ggplot(df, aes(x = `Working.Ion`)) +
geom_bar(fill = "blue", color = "black") +
labs(
title = "Histogram głównego jonu baterii",
x = "Główny Jon",
y = "Liczba"
) +
theme_light()
ggplotly(p)
p1 <- ggplot(df, aes(x = `Max.Delta.Volume`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład maksymalnej zmiany objętości dla danego kroku",
x = "Maksymalna zmiana objętości",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Average.Voltage`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład średniego napięcia",
x = "Średnie napięcie",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Gravimetric.Capacity`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład pojemności grawimetrycznej",
x = "Pojemność grawimetryczna",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Volumetric.Capacity`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład pojemności wolumetrycznej",
x = "Pojemność wolumetryczna",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Gravimetric.Energy`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład energii grawimetrycznej",
x = "Energia grawimetryczna",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Volumetric.Energy`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład energii wolumetrycznej",
x = "Energia wolumetryczna",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Atomic.Fraction.Charge`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład udziału atomowego składników w stanie naładowanym",
x = "Udział atomowy składników",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Atomic.Fraction.Discharge`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład udziału atomowego składników w stanie rozładowanym",
x = "Udział atomowy składników",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Stability.Charge`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład wskaźnika stabilności materiału w stanie naładowanym",
x = "Wskaźnik stabilności materiału",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Stability.Discharge`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład wskaźnika stabilności materiału w stanie rozładowanym",
x = "Wskaźnik stabilności materiału",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Steps`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład liczba odrębnych kroków napięcia od pełnego naładowania do rozładowana",
x = "Liczba kroków",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
p1 <- ggplot(df, aes(x = `Max.Voltage.Step`)) +
geom_histogram(fill = "blue", color = "black", alpha = 0.7) +
labs(
title = "Rozkład maksymalnej bezwzględnej różnica między sąsiednimi krokami napięcia",
x = "Maksymalna bezwzględna różnica między sąsiednimi krokami napięcia",
y = "Liczba obserwacji"
) +
theme_light()
ggplotly(p1)
cor_matrix <- df %>%
select(`Max.Delta.Volume`:last_col()) %>%
cor(method="pearson")
correlation_long <- cor_matrix %>%
as.data.frame() %>%
mutate(variable1 = colnames(cor_matrix)) %>%
pivot_longer(-variable1,
names_to = "variable2",
values_to = "correlation"
) %>%
filter(variable1 > variable2)
correlation_plot <- ggplot(
correlation_long,
aes(x = variable1, y = variable2, fill = correlation)
) +
geom_tile() +
scale_fill_gradient2(
low = "blue", mid = "white", high = "red",
midpoint = 0, limits = c(-1, 1)
) +
geom_text(aes(label = sprintf("%.2f", correlation)), size = 3) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
axis.title = element_blank()
) +
labs(fill = "Korelacja")
ggplotly(correlation_plot)
Aby zredukować korelacje między atrybutami, zastosowano funkcję findCorrelation z pakietu caret, ustawiając próg (cutoff) na 0.6. Funkcja ta identyfikuje atrybuty, które są silnie skorelowane i mogą zostać usunięte z analizy.
attributes_to_remove <- cor_matrix %>% findCorrelation(cutoff = 0.6, names = TRUE)
Atrybuty, które zostały wybrane do usunięcia: Gravimetric.Energy, Gravimetric.Capacity, Atomic.Fraction.Discharge, Stability.Charge.
Do budowy modelu predykcyjnego usunięto atrybuty Gravimetric.Energy, Gravimetric.Capacity, Atomic.Fraction.Discharge, Stability.Charge oraz Battery.ID. Dane zostały podzielone na zbiór uczący (70%) oraz testowy (30%).
in_training_data <- createDataPartition(y = df$Average.Voltage, p = 0.70, list = FALSE)
training_data <- df[in_training_data, ] %>% select(-c(Battery.ID, attributes_to_remove))
testing_data <- df[-in_training_data, ]
# ctrl <- trainControl(method = "cv", number = 2)